#include <stdint.h>
#include "check_current.h"
#include "adc2_rte.h"
static check_curr c_curr;
/*
 * 函数介绍: 产品过流保护初始化
 * 参数:
 * 返回值: {*}
 * 备注:
 */
void Overcurrent_protection_init(void)
{
    c_curr.Instantaneous_pulse = TEST_WAIT;
    c_curr.S_short_circuit = NOT_SHORT_CIRCUITED;
    c_curr.PE5_STATE = false;
    c_curr.Startup_Record = false;
    c_curr.Number_short_circuits = 0;
    RTE_GPIO_PIN_SET_LEVEL(GPIOC, OverCurCtr_O_LL_PC13_Pin, GPIO_PIN_RESET);
}

/*
 * 函数介绍: 判断自检是否达标
 * 参数:
 * 返回值: {*}
 * 备注:
 * 检测系统工作电压是否正常
 * 合格自检灯亮绿灯
 * 不合格亮红灯，并且蜂鸣3声
 */
bool frock_self_checking_OK(void)
{
    bool frock_check_result = false; /*工装自检结果*/
    float System_Voltage = 0;        /*系统电压值*/
    // float Product_Voltage = 0;/*产品电压*/
    if (ADC2_NO == ADC2_rt_init_sampling())
    {
        return frock_check_result; /*1S都没有采集好初始化电压，超时*/
    }
    System_Voltage = RTE_ADC2_CHANNEL_V(PC2_C_ADC2_INP0); /*系统电压*/
    // Product_Voltage = RTE_ADC_PRODUCT_V();/*产品电压*/

    /*系统和产品电压都在12-14V之间则电压正常*/
    if ((HIGH_VOL >= System_Voltage && LOW_VOL <= System_Voltage))
    // (HIGH_VOL >= Product_Voltage && LOW_VOL <= Product_Voltage))
    {
        frock_check_result = true;
    }
    return frock_check_result;
}

/*
 * 函数介绍: 工装自检显示结果
 * 参数:
 * 返回值: {*}
 * 备注:
 * 检测系统工作电压是否正常
 * 合格自检灯亮绿灯
 * 不合格亮红灯，并且蜂鸣3声
 */
void frock_self_checking(void)
{
    bool frock_check_result = false; /*工装自检结果*/
    static uint32_t Record_send_time = 0;
    Record_send_time = RTE_GET_TIMER(); /*记录_开始时间*/
    /*给与1S的时间让ADC先采集一次电压*/
    while (no_timeout == RTE_TIMEOUT_JUDGMENT(Record_send_time, SELF_TEST_DEL) && ADC2_NO == ADC2_rt_init_sampling())
    {
        //ADC2_Calculate_raw_value(); /*循环采样ADC*/
    }
    RTE_IWDG_REFRESH();
    frock_check_result = frock_self_checking_OK(); /*自检结果*/
    /*主界面结果显示*/
    RTE_LCD_LCD_INTERFACE_SWITCHING(MAIN_INTERFACE,frock_check_result);

    if (true == frock_check_result)
    {
        HAL_Delay(20);
        /*界面显示测试结果合格*/
        RTE_UART7_LCD_SHOW(MAIN_INTERFACE, TEST_RESULT, STATUS_QUALIFIED);
    }else{
        HAL_Delay(20);
        /*界面显示测试结果不合格*/
        RTE_UART7_LCD_SHOW(MAIN_INTERFACE, TEST_RESULT, STATUS_UNQUALIFIED);
    }
    
}

/*
 * 函数介绍: 处理开机瞬间脉冲
 * 参数:
 * 返回值: {*}
 * 备注:开机瞬间会有大于5A的瞬间脉冲持续1ms，需保持PE5脚先处于解锁状态置为高，瞬间脉冲过后，可使PE5脚处于闭锁状态置为低
 */
void Pro_instantaneous_pulses(void)
{
    if (false == c_curr.Startup_Record) /*只记录一次时间*/
    {
        c_curr.Record_send_time_5ms = RTE_GET_TIMER();
        c_curr.Startup_Record = true;
        RTE_GPIO_PIN_SET_LEVEL(GPIOC, OverCurCtr_O_LL_PC13_Pin, GPIO_PIN_SET);/*产品上电*/
    }

    /*开始解决瞬间脉冲*/
    if (TEST_WAIT == c_curr.Instantaneous_pulse && GPIO_PIN_SET == RTE_GPIO_PIN_GET_LEVEL(GPIOE, OverCurP_I_LL_PE4_Pin))
    {
        /* 有瞬间电流产生 保持PE5脚先处于解锁状态置为高*/
        RTE_GPIO_PIN_SET_LEVEL(GPIOE, Short_CTRL_PE5_Pin, GPIO_PIN_SET);
    }

    /*瞬间脉冲时间结束*/
    if (TEST_WAIT == c_curr.Instantaneous_pulse && RTE_TIMEOUT_JUDGMENT(c_curr.Record_send_time_5ms, TRANSIENT_CURRENT_DELMS))
    {
        /*脉冲时间已过，拉回PE5*/
        RTE_GPIO_PIN_SET_LEVEL(GPIOE, Short_CTRL_PE5_Pin, GPIO_PIN_RESET);
        c_curr.Instantaneous_pulse = TEST_OK;
        c_curr.Record_send_time_10s = RTE_GET_TIMER(); /*记录_上电10S_时间*/
    }
}

/*
 * 函数介绍: 短路次数记录
 * 参数:
 * 返回值: {*}
 * 备注:
 * PE4引脚为高电平，一秒后检测PE4还为高，记发生一次短路；
 * 将PE5引脚设为高电平50ms可拉低PE4，再去检测1S PE4如果还为高电平则记短路两次；
 * 在拉高PE550ms可将PE4拉低，在检测1S PE4如果还为高，则三次短路
 */
void Short_circuit_count_record(void)
{
    /*检查是否发生疑似短路      脉冲通过，PE4为高，上次短路处理结束*/
    if (TEST_OK == c_curr.Instantaneous_pulse && NOT_SHORT_CIRCUITED == c_curr.S_short_circuit && GPIO_PIN_SET == RTE_GPIO_PIN_GET_LEVEL(GPIOE, OverCurP_I_LL_PE4_Pin))
    {
        c_curr.Record_send_time_1s = RTE_GET_TIMER();    /*PE4引脚为高电平，一秒后检测PE4还为高，记发生一次短路*/
        c_curr.S_short_circuit = POSSIBLE_SHORT_CIRCUIT; /*疑似短路*/
    }

    /*延时一秒，确认本次是否需要短路计数*/
    if (POSSIBLE_SHORT_CIRCUIT == c_curr.S_short_circuit && yes_timeout == RTE_TIMEOUT_JUDGMENT(c_curr.Record_send_time_1s, SHORT_CIRCUIT_PROTECTION_1s))
    {
        if (GPIO_PIN_SET == RTE_GPIO_PIN_GET_LEVEL(GPIOE, OverCurP_I_LL_PE4_Pin))
        {
            c_curr.Number_short_circuits += 1;
            RTE_GPIO_PIN_SET_LEVEL(GPIOE, Short_CTRL_PE5_Pin, GPIO_PIN_SET); /*将PE5引脚设为高电平50ms可拉低PE4*/
            c_curr.PE5_STATE = true;                                         /*PE5拉高50ms*/
            c_curr.Record_send_time_50ms = RTE_GET_TIMER();                  /*PE5拉高50ms*/
        }
        else
        {
            c_curr.S_short_circuit = NOT_SHORT_CIRCUITED; /*未发生短路情况*/
        }
    }

    /*PE5引脚设为高电平50ms,拉低PE4*/
    if (true == c_curr.PE5_STATE && RTE_TIMEOUT_JUDGMENT(c_curr.Record_send_time_50ms, PE5_DEL50MS))
    {
        RTE_GPIO_PIN_SET_LEVEL(GPIOE, Short_CTRL_PE5_Pin, GPIO_PIN_RESET); /*将PE5拉低回来*/
        c_curr.PE5_STATE = false;                                          /*将PE5拉低回来*/
    }
}

/*
 * 函数介绍: 10s内三次短路判断是否为真正短路
 * 参数:
 * 返回值: {*}
 * 备注:
 * 如果产品上电10S内出现三次短路，报短路故障。
 */
Rt_result Triple_short_circuit(void)
{
    Rt_result result = TEST_WAIT;
    if (TEST_OK != c_curr.Instantaneous_pulse)
    {
        return TEST_WAIT;
    }
    
    /*10S内如果有出现三次短路，即为确实发生短路，如果10S超时没有发生三次短路则认为没有短路*/
    if ((3 <= c_curr.Number_short_circuits) || (yes_timeout == RTE_TIMEOUT_JUDGMENT(c_curr.Record_send_time_10s, SHORT_CIRCUIT_PROTECTION)))
    {
        if (3 <= c_curr.Number_short_circuits)
        {
            RTE_GPIO_PIN_SET_LEVEL(GPIOC, OverCurCtr_O_LL_PC13_Pin, GPIO_PIN_RESET);/*产品下电*/
            result = TEST_FAIL; /*10S内如果有出现三次短路，即为确实发生短路*/
        }
        else
        {
            result = TEST_OK;
        }
    }
    return result;
}

/*
 * 函数介绍: 产品过流保护
 * 参数:
 * 返回值: {*}
 * 备注:开机瞬间会有大于5A的瞬间脉冲持续1ms，需保持PE5脚先处于解锁状态置为高，瞬间脉冲过后，可使PE5脚处于闭锁状态置为低
 * 如果产品上电10S内出现短路，
 * PE4引脚为高电平，一秒后检测PE4还为高，记发生一次短路；
 * 将PE5引脚设为高电平50ms可拉低PE4，再去检测1S PE4如果还为高电平则记短路两次；
 * 在拉高PE550ms可将PE4拉低，在检测1S PE4如果还为高，则三次短路，报短路故障。
 */
Rt_result Overcurrent_protection(void)
{
    Rt_result result = TEST_WAIT; 
    Pro_instantaneous_pulses();
    Short_circuit_count_record();
    result = Triple_short_circuit();
    return result;
}
